#include <stdio.h>
#include "dual_light.h"

/* 最多有10个时间间隔可用,依次对应:关开关开... */
#define DL_FLASH_TIME 10

typedef struct DualLightInternal {
    int32_t type;
    int32_t light1State;
    int32_t light2State;
    uint32_t light1Count[DL_FLASH_TIME];
    uint32_t light2Count[DL_FLASH_TIME];
} DualLightInternal;

static const int32_t gDLFlashCode[DUAL_LIGHT_TOTAL][2][DL_FLASH_TIME] = {
    { /* 并排闪烁 */
        {500, 500, 0, 0, 0, 0, 0, 0, 0, 0},
        {500, 500, 0, 0, 0, 0, 0, 0, 0, 0},
    },
    { /* 并排双闪 */
        {0, 100, 100, 100, 700+500, 0, 0, 0, 0, 0},
        {0, 100, 100, 100, 700+500, 0, 0, 0, 0, 0},
    },
    { /* 交替闪烁 */
        {500, 500, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 500, 500, 0, 0, 0, 0, 0, 0, 0},
    },
    { /* 交替双闪 */
        {0, 100, 100, 100, 700+500, 0, 0, 0, 0, 0},
        {500, 100, 100, 100, 200+500, 0, 0, 0, 0, 0},
    },
    { /* 单双闪 */
        {500, 500, 0, 0, 0, 0, 0, 0, 0, 0},
        {500, 150, 200, 150, 0, 0, 0, 0, 0, 0},
    },
    { /* 流水灯 */
        {0, 100, 400, 100, 400+500, 0, 0, 0, 0, 0},
        {100, 100, 400, 100, 300+500, 0, 0, 0, 0, 0},
    },
    { /* 交换位置 */
        {50, 50, 900, 50, 100, 850, 0, 0, 0, 0},
        {0, 50, 100, 850, 50, 50, 900, 0, 0, 0},
    },
};

int32_t duallight_driver(DualLight* dl, uint32_t intervalMs)
{
    int32_t ret = -1;
    int32_t count = 0;
    int32_t light1State = 0;
    int32_t light2State = 0;
    do
    {
        if (!dl) {
            break;
        }
        if (dl->type < 0 || dl->type >= DUAL_LIGHT_TOTAL) {
            fprintf(stderr, "unknown dual light type: %d\r\n", dl->type);
            break;
        }

        DualLightInternal* dlinter = (DualLightInternal*)dl->intenal;
        if (dlinter->type != dl->type) {
            memset(dlinter, 0, sizeof(DualLightInternal));
            dlinter->type = dl->type;
        }

        for (count = 0; count < DL_FLASH_TIME; count++)
        {
            if (dlinter->light1Count[count] < gDLFlashCode[dl->type][0][count]) {
                dlinter->light1Count[count] += intervalMs;
                light1State = count % 2 == 0 ? 0 : 1;
                break;
            }
            else if (count + 1 == DL_FLASH_TIME) {
                memset(dlinter->light1Count, 0, sizeof(dlinter->light1Count));
                if (gDLFlashCode[dl->type][0][count] != 0) {
                    light1State = count % 2 == 0 ? 0 : 1;
                }
                break;
            }
        }
        for (count = 0; count < DL_FLASH_TIME; count++)
        {
            if (dlinter->light2Count[count] < gDLFlashCode[dl->type][1][count]) {
                dlinter->light2Count[count] += intervalMs;
                light2State = count % 2 == 0 ? 0 : 1;
                break;
            }
            else if (count + 1 == DL_FLASH_TIME) {
                memset(dlinter->light2Count, 0, sizeof(dlinter->light2Count));
                if (gDLFlashCode[dl->type][1][count] != 0) {
                    light2State = count % 2 == 0 ? 0 : 1;
                }
                break;
            }
        }

        /* 状态变化,产生回调 */
        if (dlinter->light1State != light1State ||
            dlinter->light2State != light2State)
        {
            dlinter->light1State = light1State;
            dlinter->light2State = light2State;
            if (dl->callback) {
                ((DUAL_LIGHT_CALLBACK)dl->callback)(dl, dlinter->light1State, dlinter->light2State);
            }
        }

    } while(0);
    return ret;
}
